# -*- coding: utf-8 -*-
# @File    : main.py
# @Author  : Xiewh
# @Email   : 1679860867@qq.com
# @Time    : 2020/11/28 18:13
# @Function: main
import os
import sys
import time
import uuid
import json
import base64
import hashlib
import requests
import subprocess
import common.yiban as yb
from common.api_url import *
from common.api_constant import *
from contextlib import closing

# 版本
APP_VERSION = '1.1.02.02'
# 机器码授权
APP_SQ = 0
# 是否为测试版本
APP_CS = 0
# 群授权
GROUP_SQ = 0
# 易班APP版本
YIBAN_VERSION = '4.1.73'
# 账号列表路径
USER_LIST_PATH = "config.xlsx"
# 模式
MODE = 2


def authorize():
    try:
        uid = uuid.UUID(int=uuid.getnode()).hex[-12:]
        print('提示：v' + APP_VERSION + ' 此版本需要测试授权码')
        print('机器码：', uid)
        pasw = input("请输入授权码：")
        uid_md5 = hashlib.md5(uid.encode('UTF-8')).hexdigest()
        v_md5 = hashlib.md5("xie167".encode('UTF-8')).hexdigest()
        uid_v_md5 = hashlib.md5((uid_md5 + v_md5).encode('UTF-8')).hexdigest()
        uid_base = base64.b64encode(uid_v_md5.encode('UTF-8'))

        if pasw.strip() != uid_base[0:12].decode('UTF-8'):
            return {'code': -1, 'msg': '提示：您的授权码不正确，请联系QQ1679860867'}
        return {'code': 1, 'msg': '验证成功'}
    except Exception as ex:
        return {'code': -1, 'msg': '授权检测出错' + str(ex)}


# 编写bat脚本，删除旧程序，运行新程序
def write_restart_cmd(version, new_file_md5):
    try:
        exe_name = "main_v" + version + '.down'
        md5param = hashlib.md5((str(GROUP_SQ) + "xie167").encode('UTF-8')).hexdigest()
        url = url_split(SERVICE_HOST, SERVICE_APP_UPDATE) + '?md5=' + md5param
        with closing(requests.get(url, stream=True)) as response:
            chunk_size = 1024  # 单次请求最大值
            content_size = int(response.headers['content-length'])  # 内容体总大小
            data_count = 0
            with open(exe_name, "wb") as file:
                for data in response.iter_content(chunk_size=chunk_size):
                    file.write(data)
                    data_count = data_count + len(data)
                    now_jd = (data_count / content_size) * 100
                    print("\r文件下载进度：%d%% - (%.2fMB/%.2fMB) - %s" % (
                        now_jd, data_count / 1024 / 1024, content_size / 1024 / 1024, exe_name), end=" ")
        print('\r')
        with open(exe_name, 'rb') as fp:
            data = fp.read()
        file_md5 = hashlib.md5(data).hexdigest()

        if file_md5 != new_file_md5:
            if os.path.isfile(exe_name):
                os.remove(exe_name)
            return {'code': -1, 'msg': '下载文件校验失败'}

        if os.path.isfile("upgrade.bat"):
            os.remove("upgrade.bat")
        b = open("upgrade.bat", 'w')
        TempList = "@echo off\n"  # 关闭bat脚本的输出
        TempList += "if not exist " + exe_name + " exit \n"  # 新文件不存在,退出脚本执行
        TempList += "echo 正在更新至最新版本...\n"
        TempList += "timeout /t 3 /nobreak\n"  # 等待10秒
        TempList += "del " + '"' + os.path.realpath(sys.argv[0]) + '"' + "\n"  # 删除当前文件
        TempList += "ren " + exe_name + " main.exe" + "\n"  # 删除当前文件
        TempList += "start main.exe" + "\n"  # 启动新程序
        TempList += "del %0"  # 运行后自动删除
        b.write(TempList)
        b.close()
        subprocess.Popen("upgrade.bat")
        sys.exit()  # 进行升级，退出此程序
    except Exception as ex:
        return {'code': -1, 'msg': '更新版本出错' + str(ex)}


# 检测版本更新
def version_check():
    try:
        with open(os.path.realpath(sys.argv[0]), 'rb') as fp:
            data = fp.read()
        file_md5 = hashlib.md5(data).hexdigest()
        md5param = hashlib.md5((str(APP_SQ) + "xie167").encode('UTF-8')).hexdigest()
        version_check_url = url_split(SERVICE_HOST,
                                      SERVICE_VERSION_API) + "?v=" + APP_VERSION + '&md5=' + file_md5 + '&sq=' + md5param + '&cs=' + str(APP_CS)
        ret = json.loads(requests.get(version_check_url).text)
        if ret['code'] != 1:
            return {'code': -1, 'msg': ret['msg'], 'v': ret['v'], 'md5': ret['md5']}
        else:
            return {'code': 1, 'msg': ret['msg']}
    except Exception as ex:
        return {'code': -2, 'msg': '版本更新检测失败' + str(ex)}


# 主函数
def main():
    global MODE
    try:
        os.system('cls')
        # 获取账号列表
        print('状态：正在读取Excel账号列表')
        get_ret = yb.get_user_list()
        if get_ret['code'] != 1:
            return print('提示：' + get_ret['msg'])

        # 设置第一个账号为投票发起账号
        ret = yb.set_yiban_main_user()
        if ret['code'] != 1:
            return print('错误：', ret['msg'])
        print('提示：账号', ret['user'], '已设置为主账号，结束前不能登录手机易班！')

        # 获取群信息
        ret = yb.get_yiban_group_list_2()
        if ret['code'] != 1:
            return print('错误：', ret['msg'])
        print("\n")
        for k, v in enumerate(ret['data']):
            print('序号：' + str(k) + '\t\t群名：' + v['name'])

        # 设置发布信息 群、点数
        while True:
            group_str = input("请输入群序号：")
            group = int(group_str)
            ret = yb.set_yiban_group(group)
            if ret['code'] != 1:
                print('错误：', ret['msg'])
            else:
                print('成功：' + ret['name'])
                break

        # 查询授权
        if GROUP_SQ != 0:
            ret = yb.get_group_sq()
            if ret['code'] != 1:
                return print('错误：', ret['msg'])

        # 获取该群EGPA
        start_egpa = 0
        ret = yb.get_yiban_group_info()
        if ret['code'] != 1:
            print('错误：获取EGPA失败', ret['msg'])
        else:
            start_egpa = ret['egpa']
            print('成功：当前EGPA', ret['egpa'])

        # for i in ret['not_user']:
        #     print('状态：账号', i['user'], '姓名：', i['name'], '未加入该群，已忽略此账号')

        # 选择模式
        print('1\t\t多条投票模式\t\t不可用')
        print('2\t\t免验证码投票\t\t正常')
        print('3\t\t只点赞模式  \t\t正常')
        MODE = input("请选择模式：")
        MODE = int(MODE)

        # 开始执行
        if MODE == 1:
            egpa_num_str = input("请输入需要的活跃点数：")
            egpa_num = int(egpa_num_str)
            # 先把前20条无需验证码的投票发布完
            print('状态：正在发布20条投票')
            ret = yb.release_beta_vote()
            if ret['code'] != 1:
                return print('错误：', ret['msg'])
            print('成功：发布完成')
            time_start = time.time()
            yb.yiban_stable_mode(egpa_num)
            # 获取该群EGPA
            ret = yb.get_yiban_group_info()
            time_end = time.time()
            if ret['code'] != 1:
                print('错误：获取EGPA失败', ret['msg'])
            else:
                print('成功：提交点数', egpa_num_str, '开始EGPA', start_egpa, '结束EGPA', ret['egpa'], '涨值',
                      round(float(ret['egpa']) - float(start_egpa), 2))
            print('成功：本此任务已完成，总耗时', round((time_end - time_start) / 60, 2), '分钟')
        elif MODE == 2:
            time_start = time.time()
            yb.yiban_20vote_model()
            # 获取该群EGPA
            ret = yb.get_yiban_group_info()
            time_end = time.time()
            if ret['code'] != 1:
                print('错误：获取EGPA失败', ret['msg'])
            else:
                print('成功：开始EGPA', start_egpa, '结束EGPA', ret['egpa'], '涨值',
                      round(float(ret['egpa']) - float(start_egpa), 2))
            print('成功：本此任务已完成，总耗时', round((time_end - time_start) / 60, 2), '分钟')
        elif MODE == 3:
            print('-----------------------------------------------------------')
            print('提示：下面输入的投票的数量，不是要刷EGPA的点数，请根据实际情况填写')
            num_str = input("请输入投票的数量(上限1000)：")
            num = int(num_str)
            if num > 1000:
                print('错误：输入数量有误')
                exit(0)
            time_start = time.time()
            yb.yiban_love_model(num)
            # 获取该群EGPA
            ret = yb.get_yiban_group_info()
            time_end = time.time()
            if ret['code'] != 1:
                print('错误：获取EGPA失败', ret['msg'])
            else:
                print('成功：开始EGPA', start_egpa, '结束EGPA', ret['egpa'], '涨值',
                      round(float(ret['egpa']) - float(start_egpa), 2))
            print('成功：本此任务已完成，总耗时', round((time_end - time_start) / 60, 2), '分钟')
    except Exception as ex:
        return {'code': -2, 'msg': '执行失败' + str(ex)}


if __name__ == "__main__":
    print('=================================================================')
    print('欢迎使用 易班小助手 当前版本v' + APP_VERSION)
    print('作者QQ：1679860867')
    if GROUP_SQ != 1:
        print('博客地址：blog.xn50.com')
        print('如果本软件能给到大家帮助请给我点个赞，最后还是希望大家合理使用\n易班，用易班记录自己学习的点点滴滴，多去易班的学习板块交流交流。')
    print('=================================================================')
    os.system('pause')
    # 机器码授权检测
    if APP_SQ != 0:
        ret = authorize()
        if ret['code'] != 1:
            print('错误：' + ret['msg'])
            os.system('pause')
            exit()
        print('成功：' + ret['msg'])

    # 版本更新检测
    print('状态：版本更新检测中...')
    check = version_check()
    if check['code'] == -2:
        print('错误：' + check['msg'])
        os.system('pause')
        exit()
    if check['code'] == -1 and APP_CS == 0:
        print('提示：有新版本正在更新...')
        ret = write_restart_cmd(check['v'], check['md5'])
        if ret['code'] != 1:
            print('错误：' + ret['msg'])
            os.system('pause')
            exit()
    print('成功：' + check['msg'])
    time.sleep(1)
    main()
    os.system('pause')  # 按任意键继续
